// JointFormer.cpp: implementation of the JointFormer class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "JointFormer.h"
#include "Joint.h"
#include "JointOwnFunction.h"
#include "SimpleExpression.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

using namespace PropertySystem;
JointFormer::JointFormer()
{
	
}

JointFormer::~JointFormer()
{
	m_FunctionStack.RemoveAll();
	m_PropertyStack.RemoveAll();
}

void JointFormer::SetJoint(Joint* pJoint)
{
	ASSERT(pJoint);

	SetProperties(pJoint);
	SetFunctions(pJoint);
}

void JointFormer::SetProperties(Joint* pJoint)
{
	PropertySystem::PropertyStack::Iterator* pIt = m_PropertyStack.NewIterator();
	for(pIt->Begin(); !pIt->End(); pIt->Next())
	{
		PropertySystem::PropertyVariable* pTempVar = static_cast<PropertySystem::PropertyVariable*>(pIt->Get());
		ASSERT(pTempVar);
		PropertySystem::PropertyVariable* pVar = pTempVar->Clone();
		ASSERT(pVar);
		
		if(!pVar->Default().IsEmpty())
		{
			SimpleExpression expr(pVar->Default(), pJoint->GetPropertyStack());
			pVar->Default((CString)expr.Caculate());
		}
		if(!pVar->ExistCondition().IsEmpty())
		{
			SimpleExpression expr(pVar->ExistCondition(), pJoint->GetPropertyStack());
			pVar->ExistCondition((CString)expr.Caculate());
		}
		if(!pVar->EffectCondition().IsEmpty())
		{
			SimpleExpression expr(pVar->EffectCondition(), pJoint->GetPropertyStack());
			pVar->EffectCondition((CString)expr.Caculate());
		}
		pJoint->GetPropertyStack()->AddProperty(pVar);
		pVar->SetOwner(pJoint);
	}
	delete pIt;
}

void JointFormer::SetFunctions(Joint* pJoint)
{
	FunctionStack::Iterator* pIt = m_FunctionStack.NewIterator();
	ASSERT(pIt);

	for(pIt->Begin(); !pIt->End(); pIt->Next())
	{
		FunctionObject* pObj = pIt->Get();
		ASSERT(pObj);

		ASSERT(pObj->IsKindOf(UE_RUNTIME_CLASS(JointOwnFunction)));
		JointOwnFunction* pFun = static_cast<JointOwnFunction*>(pObj);
		pFun->InstanceFunction(pJoint);
	}
	delete pIt;
}